Amiga-Aktuell 02/98 - Workshop
Logo




Powered by
GoldED

ARexx-Kurs - Teil 2 (von Heiko Kuschel)

»ARexx-Kurs: Übersicht

1. Einführung in ARexx.

    - Wie funktionierts? - Was brauche ich? - Installation - ein erstes kleines Programm
      - Ein- und Ausgabe - do...end
2. Programmstruktur und Ansteuerung von anderen Programmen
    - if - do...end - address - Tracing
3. Stringfunktionen
    - Stringfunktionen - Ein- und Ausgabe
4. weitere Variablenfunktionen
    - Funktionen - Operatoren
5. komplexere Programmstrukturen
    - Procedure - Libraries - sonstiges
6. Beispiele für die Vernetzung von Programmen
    - Wordworth - GoldEd - Database Professional - YAM - Miami - usw.
Änderungen vorbehalten. Spezielle Wünsche werden, wenn möglich, gerne aufgenommen.«

»

2. Programmstrukturen und Ansteuerung von externen Programmen

2.0. Vorbemerkungen
Hier wiederhole ich für Quereinsteiger noch einmal einen Teil der Vorbemerkungen, die ich zum ganzen Kurs gemacht habe.

Der Kurs wird als reine Text-Datei angefertigt, da auch Amiga aktuell u.a. in ASCII-Form verschickt wird. Um den Text etwas zu gliedern, habe ich daher ein paar "Textmarker" eingefügt.

********** unterteilt einzelne Abschnitte

__________ bezeichnet Beginn und Ende eines ARexx-Programms. Die Striche gehören nicht zum Programm!
ARexx-Befehle werden in diesem Kurs immer GROSS geschrieben, obwohl das eigentlich nicht nötig ist. Auf diese Weise kann man sie aber leichter erkennen.

Ich hoffe, daß diese Regelung den Kurs etwas leserlicher macht.

Wenn Ihr spezielle Fragen habt, etwas nicht verstanden oder Anregungen und Ideen für weitere Kursteile habt, könnt Ihr Euch gern an mich wenden. Ich selbst benutze folgende ARexx-fähige Programme und kann daher auf deren Programmierung kurz eingehen, wenn das gewünscht wird: Wordworth, GoldEd, Database Professional, YAM, Miami, Voyager, TurboCalc.

Hier meine Kontaktadresse:

Heiko Kuschel
Lehmgrubenweg 13
97280 Remlingen

E-Mail: hk0006@wuerzburg.baynet.de

Und jetzt... viel Spaß mit ARexx!

****************************************************


2.1. Die "Hausaufgabe" vom letzten Mal
Im letzten Kursteil ging es um Programmschleifen mit dem Befehl DO...END. Wie kann man nun eine Schleife so programmieren, daß sie dann abbricht, wenn man "Ende" eingibt? Dazu gibt es mehrere Möglichkeiten: Mit DO UNTIL, DO WHILE, aber auch mit DO FOREVER.

--------------------------------
/* Hello World Version 1.3.*/
DO UNTIL Eingabe="Ende"
  ECHO "Gib was ein!"
  PARSE PULL Eingabe
  ECHO "Du hast "||Eingabe||" eingegeben."
END
--------------------------------
--------------------------------
/* Hello World Version 1.4.*/
DO WHILE Eingabe~="Ende"
  ECHO "Gib was ein!"
  PARSE PULL Eingabe
  ECHO "Du hast "||Eingabe||" eingegeben."
END
--------------------------------
Die Tilde ~ ist das Negationszeichen in ARexx. ~= heißt soviel wie "ist nicht gleich".
Die zwei senkrechten Striche verknüpfen Zeichenfolgen miteinander. Die Einrückungen sind zwar nicht nötig, erhöhen aber die Übersichtlichkeit.

Wozu nun diese zwei verschiedenen Möglichkeiten, das offenbar gleiche auszudrücken (DO WHILE, DO UNTIL)?
Es gibt einen Unterschied zwischen den beiden:

DO WHILE überprüft die Bedingung am Anfang der Schleife,
DO UNTIL überprüft die Bedingung, wenn ARexx bei END angekommen ist.
Das heißt: mit DO UNTIL wird die Schleife in jedem Fall einmal durchlaufen, mit DO WHILE kann es passieren, daß ARexx sofort nach END weitermacht, falls die Bedingung nicht erfüllt ist.

Kapiert? Wenn nicht, probiere einmal, in beiden Versionen als erste Zeile nach dem Kommentar einzufügen:

--------------------------------
Eingabe="Ende"
--------------------------------
In Hello World 1.4. wird gar nichts passieren! Die Schleife wird übersprungen, denn die Bedingung ist schon erfüllt. Hello World 1.3. dagegen geht brav in die Schleife rein... und bis zum END hat sich der Wert von Eingabe schon wieder verändert.

Jetzt fehlt uns allerdings noch die dritte Möglichkeit, Schleifen zu programmieren: DO FOREVER.
Um hier eine Abfrage machen zu können, brauchen wir aber noch einen neuen Befehl. Wir müssen ARexx ja etwas in der Art mitteilen können: "Wenn Eingabe gleich "Ende" ist, dann verlasse bitte die Schleife. Und wenn nicht, dann gib die Eingabe aus."
Dieser Befehl heißt sinnvollerweise IF... THEN (...ELSE) Nach dem THEN darf allerdings nur ein einziger Befehl stehen! Wie soll man das anstellen? Oft genug muß nach so einer Abfrage doch eine ganze Menge im Programm geregelt werden. Ganz einfach: Im ersten Teil des Kurses habe ich so einen seltsamen Satz geschrieben: "Dieser Abschnitt zwischen DO und END wird intern wie ein einziger Befehl behandelt." Na, kapiert? Jawohl! Wenn nach dem THEN mehrere Befehle folgen sollen, muß vor dem ersten Befehl ein DO und nach dem letzten dieser Befehle ein END stehen.
Heiko Strohmeier hat mir dafür ein Beispiel geliefert. (Danke, Heiko!) Er hat's wagemutig mit DO FOREVER und IF...THEN probiert und das Ganze auch sehr gut gemacht:

--------------------------------
/**/
DO FOREVER
  ECHO "Gib Ende für Quit ein"
  PARSE PULL Eingabe

  IF Eingabe="Ende" THEN
  ECHO "Die eingabe war richtig "||Eingabe
  LEAVE

  IF Eingabe ~="Ende" THEN
  ECHO "Die eingabe war falsch "||Eingabe
END
--------------------------------
Das ist schon eine ganze Menge, aber es fehlt
DO... END, um funktionieren zu können. Also:
--------------------------------
/**/
DO FOREVER
  ECHO "Gib Ende für Quit ein"
  PARSE PULL Eingabe

  IF Eingabe="Ende" THEN DO
    ECHO "Die Eingabe war richtig "||Eingabe
    LEAVE
  END

  IF Eingabe ~="Ende" THEN DO
    ECHO "Die Eingabe war falsch "||Eingabe
  END
END
--------------------------------

Übrigens: IF...THEN kann auch noch mit ELSE
(ansonsten) weitergeführt werden. Eine kleine
Änderung des obigen Skripts:
--------------------------------
/**/
DO FOREVER
  ECHO "Gib Ende für Quit ein"
  PARSE PULL Eingabe

  IF Eingabe="Ende" THEN DO
    ECHO "Die Eingabe war richtig "||Eingabe
    LEAVE
  END
  ELSE DO
    ECHO "Die Eingabe war falsch "||Eingabe
  END
END
--------------------------------

****************************************************


2.2. Eine kleine "ARexx-Shell" Aus diesem Skript können wir nun sehr leicht ein Skript machen, das uns die Arbeit mit ARexx sehr erleichtert. Wie wäre es mit einer Art Shell, die ähnlich wie die DOS-Shell der Workbench Befehle direkt interpretiert, wenn man sie eingibt?
Auch dafür gibt es einen Befehl:
INTERPRET Variable
Variable wird dabei als ARexx-Befehl angesehen und direkt ausgeführt.
Also...

--------------------------------
/*Interpreter V1.0.*/
DO FOREVER
  PARSE PULL Eingabe
  IF Eingabe="Ende" THEN LEAVE
  INTERPRET Eingabe
END
--------------------------------
Tip: Speichere dieses Programm irgendwo auf Festplatte, und nimm "rx (Name des Programms)" in Deine HotKey-Liste auf, falls Du ein Programm hast, das andere Programme auf Tastendruck startet!

****************************************************


2.3. Ansteuern von anderen Programmen
2.3.1. ADDRESS

Wir haben zwar noch lange nicht alle Möglichkeiten von ARexx selbst ausgeschöpft. Trotzdem möchte ich schon jetzt darauf eingehen, wie Programme angesteuert werden können, die einen ARexx-Port zur Verfügung stellen. Denn einfache Skripte kannst Du jetzt schon selbst schreiben, und am meisten lernt man meiner Erfahrung nach, wenn man selber was ausprobiert. Und wenn's Probleme gibt... Meine Adresse steht am Anfang des Kurses.

Um ARexx mitzuteilen, welches Programm angesteuert werden soll, benötigen wir den Befehl ADDRESS. Die ARexx-Adresse (ARexx-Port), die dann folgen muß, entnimmst Du der Dokumentation des jeweiligen Programms. Z.B.:

ADDRESS YAM
ADDRESS Wordworth.1
ADDRESS TCALC
ADDRESS GOLDED.1
Eine Liste der vorhandenen Ports erhältst Du mit ECHO SHOW("PORTS") Gib das mal in der ARexx-Shell ein! Der Befehl wird weiter unten genauer erklärt.

Nach dem Befehl ADDRESS YAM werden alle Anweisungen, die ARexx nicht versteht, an die YAM-Schnittstelle weitergeleitet. Wenn nun YAM zufällig einen Befehl haben sollte, der auch als ARexx-Befehl existiert, mußt Du ihn in Anführungszeichen setzen, damit er nicht von ARexx selbst interpretiert wird.

ADDRESS COMMAND hat eine besondere Bedeutung: Damit können Shell-Befehle aufgerufen werden.

--------------------------------
ADDRESS COMMAND DIR
--------------------------------
listet das aktuelle Verzeichnis auf.
--------------------------------
ADDRESS COMMAND
DIR
--------------------------------
hat prinzipiell die gleiche Bedeutung. Im ersten Fall wird aber nur eben schnell der Befehl DIR an COMMAND übergeben, im zweiten Fall wird die Schnittstelle als COMMAND definiert und alle weiteren Befehle an COMMAND geschickt.

Also: Ich habe ein Programm, mit dem ich z.B. YAM steuere. Zwischendurch benötige ich einen einzigen COMMAND-Befehl. Dann schreibe ich ihn direkt hinter ADDRESS COMMAND, und alle folgenden Befehle gehen wieder an YAM.

------------------------    ------------------------
ADDRESS YAM                 ADDRESS YAM
(Befehle gehen an YAM)      (Befehle gehen an YAM)
ADDRESS COMMAND DIR         ADDRESS COMMAND
                            DIR
(Befehle gehen an YAM)      (Befehle gehen an COMMAND)
------------------------    ------------------------
(Wenn Du einen proportionalen Zeichensatz installiert hast, wirst Du diesen Vergleich nicht ganz so gut betrachten können. Sorry!)

ADDRESS kann auch noch ein paar Parameter mit auf den Weg bekommen: ADDRESS VALUE Variable

interpretiert Variable als solche und nimmt den Inhalt der Variablen als neuen ARexx-Port. Z.B.:

--------------------------------
Var="YAM"
ADDRESS VALUE Var
--------------------------------
Alle Befehle gehen an YAM.P> ADDRESS ohne weitere Angaben schaltet auf den vorhergehenden ARexx-Port zurück.


****************************************************


2.3.2. SHOW()
Wie kann ich nun aber feststellen, ob ein ARexx-Port wirklich existiert, ob z.B. YAM bereits gestartet ist? Dazu benötige ich wieder den Befehl SHOW(). SHOW(Option[,Name,Trennzeichen]) Option muß angegeben werden. Es gibt die folgenden Möglichkeiten:

  Clip      : Alle Einträge in der Clip-Liste
  Files     : Eine Liste der offenen logischen
              Dateinamen
  Internal  : Die interne Port-Liste
  Libraries : die geöffneten Bibliotheken
  Ports     : die allgemeinen PublicMessagePorts,
              zu denen auch die ARexx-Ports gehören.
Es reicht jeweils die Angabe des ersten Buchstabens.

Wird ein Name angegeben, dann ändert SHOW() seine Funktion. Es gibt 1 zurück, wenn der unter Name angegebene Port gefunden wurde, und 0, wenn er nicht gefunden wurde.
Also:

--------------------------------
YAM-Existiert=SHOW("P",YAM)
--------------------------------
Die dritte Möglichkeit ist die, ein beliebiges Trennzeichen für die Liste anzugeben. Am sinnvollsten ist ein "Wagenrücklauf", was der Return-Taste entspricht. Er hat den ASCII-Code 10 und wird angegeben als D2C(10) (Warum, erkläre ich im nächsten Kursteil.)
--------------------------------
ECHO SHOW("P",,D2C(10))
--------------------------------

****************************************************


2.3.3. WaitForPort
Wenn ein Programm neu gestartet wird, dauert es evtl. eine Weile, bis der ARexx-Port eingerichtet ist. Dafür gibt es den DOS-Befehl sys:rexxc/WaitForPort, der maximal 10 Sekunden wartet, bis der ARexx-Port da ist.

ADDRESS COMMAND sys:rexxc/WaitforPort YAM
wartet auf die Einrichtung des Ports YAM und macht dann weiter.


****************************************************


2.3.4. OPTIONS, RESULT und RC

Jetzt brauchen wir noch die Möglichkeit, Werte aus Programmen in ARexx zu übernehmen. Das geschieht auf folgende Weise:

a)
Ein Befehl wird an ein Programm geschickt, der einen Rückgabewert verlangt. Z.B. den Inhalt einer Zelle in TurboCalc. TurboCalc setzt diesen Befehl in die Variable RESULT (Ergebnis). In ARexx kann mit der Variable RESULT weitergearbeitet werden.

b)
Ein Befehl wird an ein Programm geschickt.
Der Befehl verursacht einen Fehler
Die Variable RC (Return Code - Rückgabecode) wird auf einen definierten
Wert gesetzt, der größer als 0 ist.
Wenn der Befehl anfällig für Fehler ist, kann man nun eine kleine
Fehlerabfrage einbauen: IF RC~=0 THEN...

c) Der Befehl ist so definiert, daß er sein Ergebnis (einen Zahlenwert) in RC ablegt. Das ist meines Erachtens zwar nicht ganz korrekt, aber durchaus nicht unüblich.
Beispiel: ISONLINE in Miami liefert 0 oder 1 in RC, je nachdem, ob Miami online ist oder nicht.

Achtung: Diese Variablen funktionieren nur, wenn vorher die entsprechende Option eingeschaltet wurde! Das geschieht mit:
OPTIONS RESULTS
Was soviel bedeutet wie: Gib mir Ergebnisse von anderen Programmen zurück.

Die anderen Optionen liefere ich am Ende des Kursteils nach. Sie sind jetzt gerade weniger interessant.


****************************************************


2.4. Erste Skripte mit anderen Programmen: Zwei Beispiele 2.4.1. Postholen.rexx
Nun können wir schon ein paar kleine Programme schreiben. Ein Beispiel: Ein Skript, das

  1. nachsieht, ob YAM gestartet ist, wenn nicht, dann YAM startet
  2. das gleiche für Miami
  3. online geht
  4. Post aus der Warteschlange verschickt
  5. Post vom Server holt
  6. nochmal nachschaut, ob inzwischen noch mehr Post eingetroffen ist
  7. YAM schließt, falls keine neue Post eingetroffen ist
  8. offline geht
  9. Miami wieder schließt.
... und so schaut das aus:
(Ich habe die Nummern der einzelnen Schritte in Kommentarzeilen mit ### eingefügt.)
--------------------------------
/* Post abholen mit Miami und YAM */
/* Version 1.0. 9.7.97 Heiko Kuschel */
OPTIONS RESULTS
YAMON=1
MIAMION=1
MIAMIONLINE=0
/*Bis hierher werden nur die Variablen so gesetzt, daß*/
/*YAMON=1: angenommen wird, daß YAM gestartet ist    */
/*MIAMION=1: das gleiche für Miami                  */
/*MIAMIONLINE=0: Miami ist offline                 */


/* ############ Teil 1 ############ */
if ~show(PORTS, YAM) then do
   address command
   "run Comm:YAM/YAM"
                      /*Diese Zeile mußt Du ändern!*/
   "sys:rexxc/waitforport YAM"
   YAMON=0
   end
/* Wenn YAM nicht bereits gestartet ist, dann*/
/* starte es                                 */
/* warte auf den ARexx-Port von YAM          */
/* merke dir, daß YAM nicht gestartet war    */
/* Natürlich mußt Du den Pfad entsprechend   */
/* anpassen.                                 */

/* ############ Teil 2 ############ */
if ~show(PORTS, MIAMI.1) then do
   Address command
   "run Comm:miami11a/miami"
   "sys:rexxc/waitforport MIAMI.1"
   MIAMION=0
   end
/* Genau wie bei YAM. */

/* ############ Teil 3 ############ */
address Miami.1
   isonline
   if RC=1 then do
      MIAMIONLINE=1
      end
   else do
     ONLINE
     end
/*Hier sind zwei Befehle drin, die zum Befehlsschatz */
/*von Miami gehören:                                 */
/*ISONLINE gibt RC=0 oder 1 zurück                   */
/*ONLINE geht online.                                */
/*Die Zeile MIAMIONLINE=1 merkt sich, daß Miami schon*/
/*online war. Sonst wird am Ende des Programms u.U.  */
/*eine Verbindung unterbrochen, wo doch Dein Browser */
/*gerade 98% einer 3-Megabyte-Datei geladen hatte... */

/* ############ Teil 4 ############ */
address YAM
   Mailsendall
/* ############ Teil 5 ############ */
   Mailcheck
   if RESULT>0 then YAMON=1
/* ############ Teil 6 ############ */
   Mailcheck
   if RESULT>0 then YAMON=1
/* ############ Teil 7 ############ */
   if YAMON=0 then quit
/*Das ist der Teil, in dem eigentlich was passiert.   */
/*Mailsendall ist ein YAM-Befehl, der alle anstehenden*/
/*Mails sendet.                                       */
/*Mailcheck holt Post ab und gibt in RESULT die Anzahl*/
/*der Mails zurück.                                   */
/*Wenn mehr als 0 Mails abgeholt wurden, dann wird die*/
/*Variable YAMON auf 1 gesetzt. YAM wird dann am Ende */
/*nicht geschlossen, damit Du die neuen Mails auch    */
/*lesen kannst.                                       */

/* ############ Teil 8 ############ */
Address MIAMI.1
if MIAMIONLINE=0 then do
   offline
   end
/*Wenn Miami vorher nicht online war,     */
/*geht es jetzt auch wieder offline.     */
/* ############ Teil 9 ############ */
if MIAMION=0 then do
   quit
   end
/*Und wenn Miami gar nicht gestartet war,      */
/*wird es jetzt wieder beendet.               */
--------------------------------
Das Ganze funktioniert leider noch nicht mit YAM 2.0., da dort ARexx noch nicht vollständig implementiert ist. Wenn Du das Skript nutzen willst, mußt Du es mit YAM 1.3.x tun.

Achtung: Lasse das Skript nicht unbeaufsichtigt laufen!
Wenn beim Aufbau der Verbindung ein Fehler auftritt, meldet Miami das mit einem Requester und bleibt so lange online, bis Du auf "OK" geklickt hast. Wenn Du erst nach ein paar Stunden zurückkommst, hast Du eine ziemlich hohe Telefonrechnung... Sobald Miami erst mal online ist, vertraue ich selber meinem Skript. (Bei mir dauert das Laden manchmal eine Stunde.)


****************************************************


2.4.2. Dokumente-Drucken.rexx
Da vermutlich nicht alle hier eine Internet-Verbindung haben, noch ein praktisches Beispiel für Wordworth, an dem ich gleichzeitg noch ein paar Dinge zeigen will
. Dieses Skript tut folgendes:

  1. nach einem beliebigen Dokument fragen
  2. fragen, ob noch ein weiteres Dokument gedruckt werden soll Schritte 1-2 wiederholen, bis bei 2. "nein" angeklickt wird
  3. ein Dokument nach dem anderen laden und drucken.
Dazu benötigen wir allerdings noch eine neue Information. Also bitte ich alle, die kein Wordworth haben, trotzdem noch den nächsten Absatz zu lesen! Variablen können in ARexx wie in vielen anderen Sprachen mehrere Dimensionen haben. Das sieht folgendermaßen aus: Name.Nummer - Damit kann man schon eine kleine Datenbank realisieren...

Name.1="Meyer"
Strasse.1="Meyerstraße 11"
Name.2="Hagenbüchel"
Strasse.2="Briefkastenstr. 188"

Kapiert? An den Namen der Variablen wird ein Punkt angehängt, danach kommt eine Zahl. Jeder Name in Verbindung mit jeder Zahl ist eine eigene Variable mit einem eigenen Wert!

Das Schöne in ARexx, im Gegensatz zu den meisten anderen Sprachen, die ich kenne:

Du mußt ARexx nicht von vornherein sagen, welches die höchste Zahl ist. Und man kann auch dem "Stamm" (so heißt der Teil der Variable, den ich als "Name" bezeichnet habe) einen Wert zuweisen, der dann für alle Untervariablen gilt.
Z.B.:

--------------------------------
PLZ.=97280  /*Beachte den Punkt!*/
Zahl=12
echo PLZ.1
echo PLZ.10
echo PLZ.Zahl
echo PLZ.PLZ
--------------------------------
Im letzten Fall wird der Wert der Variablen PLZ.97280 ausgegeben... und der ist auch 97280!
Auch mehrdimensionale Variablen sind möglich: Variable.Zahl.Zahl2

Und nun zu dem Programm. Es ist übrigens mit Dokumentation auch im Aminet zu haben, unter util/rexx/WW-Print.lha

Außerdem sind noch zwei String-Funktionen drin, die eigentlich erst nächstes Mal behandelt werden sollen. Es sind: LASTPOS(Buchstabe,Zeichenkette) gibt die Position des Buchstabens an, an der er zum letzten Mal in einer Zeichenkette auftritt.

--------------------------------
Position=LASTPOS("e","Heiko Kuschel")
ECHO Position
--------------------------------
ergibt 11 LEFT(Zeichenkette,Zahl) ergibt den linken Teil einer Zeichenkette, bis zum xten Zeichen.
--------------------------------
ECHO LEFT("Heiko Kuschel",6)
--------------------------------
ergibt "Heiko"
--------------------------------
/* Wordworth 5 ARexx-Skript zum
Drucken beliebig vieler Dateien  */
/* Heiko Kuschel 27. Juni 1996 */
/* basierend auf WW5-Skript von
MJ (Digita)                    */
/* FREEWARE, falls Digita kein Copyright
beansprucht.         */
OPTIONS RESULTS

Nummer=0
Pfad =""
DO forever
Nummer=Nummer+1

  RequestFile TITLE "Zu druckendes Dokument wählen..." PATH Pfad
 File.Nummer = Result
/*RequestFile ist ein Wordworth-Befehl. Mit der Option PATH kann
wahlweise angegeben werden, welcher Pfad im Requester voreingestellt
sein soll.*/
/*Das Resultat der Abfrage steht in RESULT. RC ist größer 0,
wenn Abbruch */
/*gewählt wurde.*/
/*Dieses Skript geht davon aus, daß es
direkt aus Wordworth gestartet */
/*wurde. Dann ist ADDRESS überflüssig, die Adresse
ist bereits richtig */
/*gesetzt. Da Wordworth für jedes Textfenster einen eigenen
ARexx-Port*/
/*aufmacht, ist es auch ziemlich schwierig herauszufinden,
welchen man */
/*adressieren kann. Wenn ich in WW das erste Fenster schließe,
geht der */
/*ARexx-Port mit dem Namen Wordworth.1 mit flöten.
Dann kann ich natürlich*/
/*nicht einfach ADDRESS Wordworth.1 schreiben.
Ziemlich kompliziert, wie */
/*gesagt. :-( */

        Strich=Lastpos("/",File.Nummer)
        Pfad=""
        if (Strich>0) then Pfad=Left(File.Nummer,(Strich-1))
/*Hier "extrahiere" ich den Pfad des zuletzt
gewählten Dokuments, damit */
/*der Benutzer sich nicht jedesmal durch alle Verzeichnisse und */
/*Unterverzeichnisse durchwühlen muß. Er findet sich
im nächsten*/
/*Requester (wenn weitere Dokumente ausgewählt werden)
wieder im */
/*gleichen Verzeichnis, in dem er bereits war. */
        if (RC > 0) THEN Exit
/*Wenn im File-Requester "Abbruch" geklickt wurde, wird
das Programm mit */
/*EXIT vollständig abgebrochen.*/

  RequestResponse PROMPT "Möchten Sie ein weiteres Dokument drucken?"
  if (RC > 0) THEN leave
/*Frage danach, ob ein weiteres Dokument gedruckt werden
soll. Wenn nein, */
/*wird die DO FOREVER-Schleife mit LEAVE verlassen, wenn
doch, geht's */
/*oben wieder weiter... mit dem Pfad des zuletzt
gewählten Dokuments */
/*als Vorgabe. */

END

        New
        Address Value Result
/*NEW öffnet ein neues Fenster in Wordworth und
gibt in Result den */
/*ARexx-Port zurück. Jedes Wordworth-Fenster hat
einen eigenen Port: */
/*Wordworth.1, Wordworth.2 usw. */

Do Zaehler=1 to Nummer
        Open FILENAME File.Zaehler
        Print
end
/*In File.1 steht der Name des ersten zu druckenden
Dokuments, */
/*in File.2 der des zweiten usw. */
        Close FORCE

--------------------------------

****************************************************


2.4.3. Hinweise fürs eigene 'rumexperimentieren Leider sind die ARexx-Ports bei manchen Programmen etwas gewöhnungsbedürftig.
Database Professional akzeptiert Befehle offenbar nur in GROSSBUCHSTABEN. Wordworth gibt keinerlei Fehlermeldungen aus, wenn das Programm direkt aus Wordworth gestartet wurde, und ist in der Befehlssyntax sehr pingelig, in der Dokumentation aber sehr dürftig. Beckertext hat einen Befehl, den ich genau so eingegeben habe, wie in der Anleitung beschrieben, nicht akzeptiert. Usw. Da hilft nur eines: Probieren, probieren, probieren. Und "Trace", das unten beschrieben wird.
Schau Dir einfach mal verschiedene ARexx-Skripte an und versuche herauszufinden, was sie machen, und wie sie das machen. Für Wordworth 6 existiert eine überarbeitete (ergänzte und verbesserte) Version der Dokumentation der ARexx-Befehle im Aminet. Verzeichnis: docs/misc/WW6-Germ-ARexx.lha

Wichtig zu wissen ist die Behandlung von Anführungszeichen in ARexx- Skripten.
Wenn Du ein " an das ausführende Programm senden willst, mußt Du es in '' setzen (Linke-Alt-ä).
Wenn Du ein ' an das ausführende Programm senden willst, mußt Du es in "" setzen.
Beide Anführungszeichen sind geeignet, einen Befehl einzuschließen. "END" ist gleichbedeutend mit 'END'. Beides wird an ein externes Programm gesendet.
Vor dem Ausführen einer Zeile entfernt ARexx immer die "äußersten" Anführungszeichen. Aus "END" wird END, das dann an das externe Programm geschickt wird.

--------------------------------
ADDRESS TCALC /*Das ist TurboCalcs Adresse*/
variable="Hallo"
Put Variable  /* Fügt den Wert von Variable in die aktuelle Zeile ein*/
"NACHUNTEN()" /* Setzt den Cursor eine Zeile tiefer */
'Put Variable' /* Da Variable mit in Anführungszeichen steht, wird */
               /* es als Text interpretiert, nicht als der Name einer*/
               /* Variablen. In TurboCalc steht in dieser Zeile VARIABLE */
"NACHUNTEN()"
Put '"Hallo Du da"'
"NACHUNTEN()"
Put '"Ich sage mal '||Variable||' zu dir"'
'NACHUNTEN()'
'Put "Ich sage mal '||Variable||' zu dir"'
--------------------------------

Schau Dir mal mit Trace (vgl. u.) an, was ARexx aus den einzelnen Zeilen macht!


****************************************************


2.5. Trace
"Trace" (Spuren) ist eine Möglichkeit, herauszufinden, was Dein Programm denn nun eigentlich tut.
Es handelt sich im wesentlichen um die schon im ersten Kursteil kurz erwähnten DOS-Programme im Verzeichnis sys:rexxc Du mußt diese Befehle also in eine Shell eingeben, nicht in ein ARexx- Programm! (Dort höchstens mit ADDRESS COMMAND)

TCO  Trace Console Open
     Öffnet ein eigenes Trace-Fenster
TCC  Trace Console Close
     schließt das Fenster wieder
TS   Trace Start
     Ab sofort werden alle Befehle in der Form,
     wie sie ARexx interpretiert, ausgegeben. Ergebnisse werden
     angezeigt. Der nächste Befehl wird erst nach
     Drücken von Return ausgeführt.
TE   Trace End
     Tracing wird wieder beendet. Für den momentan
     ausgeführten Befehl muß im Trace-Fenster
     noch einmal Return gedrückt werden.
In der Trace-Console können auch Befehle eingegeben werden, die als Teil des Programms betrachtet werden.
= wiederholt die Ausführung der letzten Zeile -x überspringt die nächsten x Befehle

In der Trace-Console werden vor der Auflistung der abgearbeiteten Befehle folgende Codes vorangestellt:

+++ Befehls- oder Syntaxfehler
>C> erweiterter zusammengesetzter Name
>F> Ergebnis eines Funktionsaufrufs
>L> Sprungmarkenklausel
>O> Ergebnis einer zweistelligen Operation
>P> Ergebnis einer Präfix-Operation
>U> nicht initialisierte Variablen
>V> Wert einer Variablen
>>> Ergebnis eines Ausdrucks
>.> Wert eines "Platzhalter"-Tokens
Es gibt allerdings auch einen Befehl, der innerhalb eines ARexx-Programms angewendet werden kann. Er heißt sinnvollerweise TRACE
und hat eine Menge Optionen:
ALL              Zeigt alles an.
BACKGROUND       Es findet keine Ablaufverfolgung statt.
                 Was immer das auch heißt.
COMMANDS         Zeigt alles an, was an ein externes
                 Programm geschickt wird.
ERRORS           Zeigt alle Fehler an. (Befehle,
                 die RC~=0 liefern.)
INTERMEDIATES    Zeigt alle Zwischenwerte an.
LABELS           Zeigt alle Sprunganweisungen an (
                 die hatten wir noch nicht).
NORMAL           Zeigt alle Befehle an, die den
                 voreingestellten Schweregrad
                 (OPTIONS FAILAT x) überschreiten
                 (RC>=x).
RESULTS          Zeigt alle Ergebnisse an.
SCAN             Prüft das Skript auf Fehler, ohne
                 es auszuführen
OFF              Aus.
!                Schaltet das Versenden von Befehlen
                 an externe Programme
                 ab, beim zweiten Aufruf wieder an.
?                Entspricht TS in DOS. Nach jedem Befehl
                 wird gewartet. Nochmal schaltet den
                 Modus wieder aus.
Es reicht jeweils die Angabe des ersten Buchstabens: TRACE R ? kann auch in Verbindung mit den anderen Optionen verwendet werden: TRACE R?

Außerdem gibt es die Funktion TRACE()

ECHO TRACE()
oder:
Ergebnis=TRACE() ECHO Ergebnis
gibt die momentane Trace-Einstellung aus.
Außerdem können innerhalb der Klammern die gleichen Parameter angegeben werden wie bei TRACE.
ECHO TRACE("A")
setzt Tracing auf All.


****************************************************


2.6. Übersicht über die neuen Befehle und Funktionen

IF...THEN...ELSE
INTERPRET Ausdruck
ADDRESS (VALUE|COMMAND)
Ergebnis=SHOW("C|F|I|L|P",Name,Trennzeichen)
TRACE Optionen
Ergebnis=TRACE()
Ergebnis=LASTPOS(Zeichen,Zeichenkette)
Ergebnis=LEFT(Zeichenkette,Zahl)

OPTIONS [NO] RESULTS die unten genannten Systemvariablen werden
                                                 (de-)aktiviert
  FAILAT x     RC>=x wird als Fehler interpretiert
  PROMPT Ausdr.Bei PULL und PARSE PULL wird Ausdr. vorangestellt
  [NO] CACHE:  Der interne Befehlscache, der die Ausführung von
               Schleifen beschleunigt, wird ab- bzw. angestellt.
               Normalerweise an.
  ohne Parameter werden die Einstellungen wieder zurückgesetzt.

DOS-Befehle:
TCO
TCC
TS
TE
WaitForPort

Systemvariablen:
RESULT
RC
So, das war's für diesmal. Ich hoffe, es ist mir gelungen, Dich ein wenig in die Materie einzuführen. Probiere einfach mal aus, Deine eigenen Skripte zu schreiben! Und im Aminet gibt es ein eigenes Verzeichnis util/rexx, in dem auch viele Skripte darauf warten, von Dir erforscht zu werden. Bitte schreibe mir, wenn Du etwas nicht verstanden hast oder bestimmte Probleme hast. Auch, welche Programme Du programmieren willst, und zu welchem Zweck. Wenn möglich, werde ich darauf eingehen.«


  [TOP]  
Homepage
letzte Meldung

Ausgabe 03/98

Intern
[Workshop]
Test
Spiele
Interview
Amiga News
PowerUp-to-date
Produktvorstellungen
diverse News
Newsflash
Gerüchteküche
Abscließend


Archiv
Abo
Kontakt